/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.jh.query.jquery;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 *
 * @author namhh
 */
public class BTable {

    private String _tableName;
    public Query QUERY;

    public BTable(String tableName) {
        _tableName = tableName;
        QUERY = new Query();
    }

    private Set<BCol> cols = new HashSet<>();

    public BTable addCol(BCol bcol) {
        cols.add(bcol);
        return this;
    }

    public String aliasName() {
        return hashCode() + "";
    }

    protected enum TYPE {

        AND(" AND "), OR(" OR "), INNER_JOIN(" INNER JOIN ");

        private final String type;

        private TYPE(String type) {
            this.type = type;
        }

        public String getVal() {
            return type;
        }

    }
    
    protected enum JOIN_TYPE {

         INNER_JOIN(" INNER JOIN ");

        private final String type;

        private JOIN_TYPE(String type) {
            this.type = type;
        }

        public String getVal() {
            return type;
        }

    }

    protected enum OPERATION {

        EQUAL(" = "), LESS_EQUAL(" <= "), GREATER_EQUAL(" >= ");

        private final String type;

        private OPERATION(String type) {
            this.type = type;
        }

        public String getVal() {
            return type;
        }

    }

    public class Query {

        private final List<BCol> selectedColumns = new ArrayList<BCol>();

        private String _where = " ";
        private String _join = " ";

        public Query setSelectedColumns(BCol column) {
            selectedColumns.add(column);
            return this;
        }

        public String getEntityAlias() {
            return "t" + aliasName();
        }

        public String getEntityOperation() {
            return "t" + aliasName() + ".";
        }

        private String getSELECT() {
            String ret = " SELECT ";
            if (!selectedColumns.isEmpty()) {

                for (int i = 0; i < selectedColumns.size(); i++) {
                    ret += " " + getEntityOperation() + selectedColumns.get(i);
                    if (i + 1 < selectedColumns.size()) {
                        ret += " , ";
                    }
                }

            } else {
                ret += " * ";
            }
            return ret;
        }

        private String getFROM() {
            return " FROM " + _tableName + " " + getEntityAlias();
        }

        public Query addCondtion(TYPE type, BCol cols, OPERATION operation, Object val) {

            String col = getEntityOperation() + cols;
            if (val instanceof String) {
                val = "LOWER('" + val + "')";
                col = "LOWER(" + cols + ")";
            }
            if (_where.contains("WHERE")) {
                _where += type.getVal() + col + operation.getVal() + val;
            } else {
                _where += "WHERE " + col + operation.getVal() + val;
            }
            return this;

        }

        public Query join(Query other, JOIN_TYPE type, List<BCol> joinOn) {
            String on = "";
            for (int i = 0; i < joinOn.size(); i++) {
                on += getEntityOperation() + joinOn.get(i) + " = " + other.getEntityOperation() + joinOn.get(i);
                if (i + 1 < joinOn.size()) {
                    on += " AND ";
                }
            }

            _join = type.getVal() + "\n ("
                    + other.toQueryString() + "\n" + " )" + other.getEntityAlias() + " \n ON"
                    + "(" + on + ")";
            return this;
        }

        public String toQueryString() {
            String ret = getSELECT() + "\n" + getFROM() + "\n" + _join + "\n" + _where;
            clear();
            return ret;

        }

        public void clear() {
            selectedColumns.clear();
            _join = "";
            _where = "";
        }
    }

}
